package com.lysj.merchant.desk.service;

import cn.hutool.core.util.ImageUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lysj.admin.utils.exception.BaseException;
import com.lysj.admin.utils.json.JacksonUtil;
import com.lysj.admin.utils.spring.foundation.base.BaseService;
import com.lysj.admin.utils.validation.annotation.Valid;
import com.lysj.admin.utils.web.HttpUtil;
import com.lysj.admin.utils.web.ParamUtil;
import com.lysj.admin.utils.web.Resp;
import com.lysj.admin.utils.web.SelectItem;
import com.lysj.merchant.desk.domain.Desk;
import com.lysj.merchant.desk.domain.DeskRoom;
import com.lysj.merchant.desk.domain.DeskType;
import com.lysj.merchant.desk.dto.DeskAddDto;
import com.lysj.merchant.desk.dto.DeskQueryDto;
import com.lysj.merchant.desk.repository.DeskRepository;
import com.lysj.merchant.desk.vo.DeskVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.imageio.ImageIO;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.transaction.Transactional;
import javax.annotation.Resource;
import java.awt.*;
import java.io.*;
import java.util.*;
import java.util.List;

/**
 * @author Created by drj on 2019-03-07 14:35:25
 * @description 餐桌服务层
 */
@Slf4j
@Service
@Transactional
public class DeskService implements BaseService<Desk> {

    @Resource
    private DeskRepository deskRepository;

    @Resource
    private DeskRoomService deskRoomService;

    @Resource
    private DeskTypeService deskTypeService;

    @Resource
    private EntityManager entityManager;

    @Value("${wxconfigInfo.appId}")
    public String appId;

    @Value("${wxconfigInfo.appSecrct}")
    public String appSecrct;

    @Value("${xiaochengxu.bgphoto}")
    public String bgphoto;



    @Override
    public DeskRepository getRepository() {
        return deskRepository;
    }

    /*
     * @author drj
     * @date 2019-03-13 15:18
     * @Description :获取餐桌列表
     */
    public Map<String, Object> findDeskList(DeskQueryDto deskDto) {
        if (ParamUtil.isBlank(deskDto.getPageSize())) {
            deskDto.setPageSize(10);
        }
        if (ParamUtil.isBlank(deskDto.getPageNumber())) {
            deskDto.setPageNumber(0);
        } else {
            deskDto.setPageNumber(deskDto.getPageNumber() - 1);
        }
        StringBuilder queryStr = new StringBuilder();
        queryStr.append("SELECT NEW com.lysj.merchant.desk.vo.DeskVo(a.id,a.name,b.id,b.name,c.id,c.name,c.minAmount,c.maxAmount,a.minMoney,a.status,a.createTime,a.cusNumber) FROM  Desk  a, DeskRoom b, DeskType c WHERE" +
                " a.delFlag=1 AND a.deskRoomId=b.id AND a.deskTypeId=c.id AND a.storeId=? ");
        // 查询条件拼接
        List<Object> params = new ArrayList<>();
        StringBuilder sb = new StringBuilder();
        // 当前登陆门店id
        params.add(deskDto.getStoreId());
        if (!ParamUtil.isBlank(deskDto.getDeskRoomId())) {
            sb.append(" AND a.deskRoomId=?");
            params.add(deskDto.getDeskRoomId());
        }
        if (!ParamUtil.isBlank(deskDto.getDeskTypeId())) {
            sb.append(" AND a.deskTypeId=?");
            params.add(deskDto.getDeskTypeId());
        }
        if (!ParamUtil.isBlank(deskDto.getStatus())) {
            sb.append(" AND a.status=?");
            params.add(deskDto.getStatus());
        }
        /**
         * 查询总数
         */
        StringBuilder countSb = new StringBuilder();
        countSb.append("SELECT COUNT(*) FROM  Desk  a, DeskRoom b, DeskType c WHERE a.delFlag=1 AND a.deskRoomId=b.id AND a.deskTypeId=c.id AND a.storeId=?");
        Query q = entityManager.createQuery(countSb.append(sb).toString());
        for (int i = 0; i < params.size(); i++) {
            q.setParameter(i + 1, params.get(i));
        }
        sb.append("ORDER BY  a.name ");
        Query query = entityManager.createQuery(queryStr.append(sb).toString());
        for (int i = 0; i < params.size(); i++) {
            query.setParameter(i + 1, params.get(i));
        }
        query.setFirstResult(deskDto.getPageNumber() * deskDto.getPageSize());
        query.setMaxResults(deskDto.getPageSize());
        List<DeskVo> fundRepaymentVos = query.getResultList();
        Map<String, Object> map = new HashMap<>();
        map.put("total", Long.parseLong(q.getSingleResult().toString()));
        map.put("rows", fundRepaymentVos);
        return map;
    }


    /*
     * @author drj
     * @date 2019-03-13 15:18
     * @Description :获取空闲餐桌
     */
    public List<SelectItem> showFreeDesks(String storeId, String deskRoomId, String deskTypeId) {
        StringBuilder sb = new StringBuilder();
        List<Object> params = new ArrayList<>();
        sb.append("select new com.lysj.admin.utils.web.SelectItem(id,name) from Desk  WHERE status=1 AND delFlag=1 AND storeId=?");
        params.add(storeId);
        if (!ParamUtil.isBlank(deskRoomId)) {
            sb.append(" AND deskRoomId =?");
            params.add(deskRoomId);
        }
        if (!ParamUtil.isBlank(deskTypeId)) {
            sb.append(" AND deskTypeId =?");
            params.add(deskTypeId);
        }
        Query query = entityManager.createQuery(sb.toString(), SelectItem.class);
        for (int i = 0; i < params.size(); i++) {
            query.setParameter(i + 1, params.get(i));
        }
        List<SelectItem> selectItems = (List) query.getResultList();
        //格式化数据
        return selectItems;
    }

    /*
     * @author drj
     * @date 2019-03-13 15:21
     * @Description :根据餐桌id,获取餐桌位置,餐桌类型信息
     */
    public Map<String, Object> getDeskInfo(String deskId) {
        Map<String, Object> map = new HashMap<>();
        Desk desk = deskRepository.findOne(deskId);
        DeskRoom deskRoom = deskRoomService.findOne(desk.getDeskRoomId());
        map.put("deskRoom", deskRoom.getName());
        DeskType deskType = deskTypeService.findOne(desk.getDeskTypeId());
        map.put("deskType", deskType.getMinAmount() + deskType.getMaxAmount());
        return map;
    }

    public String saveRewrite(@Valid DeskAddDto deskDto) throws IOException {
        DeskRoom deskRoom = deskRoomService.findOne(deskDto.getDeskRoomId());
        File yuantuFile = new File("C:/desk/" + deskDto.getStoreId() + "/yuantu/");
        if (!yuantuFile.exists()) {
            yuantuFile.mkdirs();
        }

        File waterMarkFile = new File("C:/desk/" + deskDto.getStoreId() + "/waterMark/");
        if (!waterMarkFile.exists()) {
            waterMarkFile.mkdirs();
        }

        if (deskDto.getAmount() == 1) {
            if (ParamUtil.isBlank(deskDto.getSerialNumber())) {
                throw new BaseException("请输入桌台编号", Resp.Status.PARAM_ERROR.getCode());
            }
            Desk desk = deskInit(deskDto.getPrefix() + deskDto.getSerialNumber(), deskDto);
            desk = deskRepository.save(desk);
            //生成小程序餐桌二维码
            String path = yuantuFile.getPath() + "/" +
                    deskDto.getPrefix() + deskDto.getSerialNumber() + ".png";
            String waterPath = waterMarkFile.getPath() + "/" +
                    deskDto.getPrefix() + deskDto.getSerialNumber() + ".png";
            //原图
            createDeskPhoto(path, desk.getStoreId(), desk.getId());
            //获取水印图片
            createWaterMark(bgphoto, new File(path), deskRoom.getName() + deskDto.getPrefix() + deskDto.getSerialNumber(), waterPath);

            return "操作成功";
        }
        for (int i = 1; i <= deskDto.getAmount(); i++) {
            Desk desk = deskInit(deskDto.getPrefix() + "00" + i, deskDto);
            desk = deskRepository.save(desk);
            //生成小程序餐桌二维码
            String path = yuantuFile.getPath() + "/" +
                    deskDto.getPrefix() + "00" + i + ".png";
            String waterPath = waterMarkFile.getPath() + "/" +
                    deskDto.getPrefix() + "00" + i + ".png";
            createDeskPhoto(path, desk.getStoreId(), desk.getId());
            //获取水印图片
            createWaterMark(bgphoto, new File(path), deskRoom.getName() + deskDto.getPrefix() + "00" + i, waterPath);
        }
        return "操作成功";
    }

    //餐桌初始化
    private Desk deskInit(String name, DeskAddDto deskDto) {
        Desk desk = new Desk();
        desk.setStoreId(deskDto.getStoreId());
        desk.setName(name);
        desk.setDeskRoomId(deskDto.getDeskRoomId());
        desk.setDeskTypeId(deskDto.getDeskTypeId());
        desk.setMinMoney(deskDto.getMinMoney());
        desk.setCusNumber(0); //用餐人数设置为0
        desk.setCustomerId(""); //用户id设置为空
        desk.setStatus(Desk.Status.FREE.getCode()); //餐桌状态设置为空闲状态
        return desk;
    }

    /*
     * @author drj
     * @date 2019-03-26 17:24
     * @Description :生成小程序二维码
     */
    private void createDeskPhoto(String path, String storeId, String deskId) {
        StringBuilder sb = new StringBuilder();
        sb.append("appid=").append(appId).append("&secret=").append(appSecrct).append("&grant_type=client_credential");
        String tokenJson = HttpUtil.sendGet("https://api.weixin.qq.com/cgi-bin/token", sb.toString());
        Map<String, String> map = JacksonUtil.toStringMap(tokenJson);

        RestTemplate rest = new RestTemplate();
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {
            String url = "https://api.weixin.qq.com/wxa/getwxacode?access_token=" + map.get("access_token");
            Map<String, Object> param = new HashMap<>();
            param.put("path", "pages/index/index?deskId=" + deskId + "&storeId=" + storeId);
            param.put("width", 430);
            param.put("auto_color", false);
            //拼接自定义参数
//            param.put("scene", "&deskId=" + deskId );
            Map<String, Object> line_color = new HashMap<>();
            line_color.put("r", 0);
            line_color.put("g", 0);
            line_color.put("b", 0);
            param.put("line_color", line_color);
            log.info("调用生成微信URL接口传参:" + param);
            ObjectMapper objectMapper = new ObjectMapper();
            String s = objectMapper.writeValueAsString(param);
            List list = new ArrayList();
            list.add("Content-Type");
            list.add("application/json");
            MultiValueMap headers = new LinkedMultiValueMap<>();
            headers.put("header", list);
            HttpEntity requestEntity = new HttpEntity(s, headers);
            ResponseEntity<byte[]> entity = rest.
                    exchange(url, HttpMethod.POST, requestEntity, byte[].class, new Object[0]);
            log.info("调用小程序生成微信永久小程序码URL接口返回结果:" + entity.getBody());
            byte[] result = entity.getBody();
            log.info(Base64.encodeBase64String(result));
            inputStream = new ByteArrayInputStream(result);

            File file = new File(path);
            if (!file.exists()) {
                file.createNewFile();
            }
            outputStream = new FileOutputStream(file);
            int len = 0;
            byte[] buf = new byte[1024];
            while ((len = inputStream.read(buf, 0, 1024)) != -1) {
                outputStream.write(buf, 0, len);
            }
            outputStream.flush();
        } catch (Exception e) {
            log.error("调用小程序生成微信永久小程序码URL接口异常", e);
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private static void createWaterMark(String backGroundPath, File file, String text, String desPath) throws IOException {
        File source = new File(backGroundPath);//背景图片地址
        File des = new File(desPath);//图片目的地址
        ImageUtil.scale(file, file, 124, 124, null);
        ImageUtil.pressText(source, des, text, Color.black, new Font("宋体", Font.PLAIN, 18), 0, -74, 1f);
        ImageUtil.pressImage(des, des, ImageIO.read(file), 0, 0, 1f);
    }
}